package compute;

import java.util.ArrayList;
import java.util.Random;

import data.DataBloc;
import data.Key;

public class TdeaCbc extends Mode {

	public TdeaCbc(KeyingOption op) {
		blocEncrypter = new TDEA(op);
	}

	public TdeaCbc(Key k1, Key k2, Key k3) {
		blocEncrypter = new TDEA(k1, k2, k3);
	}

	@Override
	public byte[] encrypt(String plainText) {

		DataBloc C = generateIV();

		ArrayList<DataBloc> plainTextDataBloc = DataBloc.toDataBloc(plainText);

		ArrayList<DataBloc> cypherTextDataBloc = new ArrayList<DataBloc>();
		cypherTextDataBloc.add(C);

		for (DataBloc dataBloc : plainTextDataBloc) {
			byte[] Ci_1 = C.getBytes();
			byte[] Ci = dataBloc.getBytes();
			byte[] result = new byte[Ci.length];
			for (int j = 0; j < Ci.length; j++) {
				result[j] = (byte) (Ci_1[j] ^ Ci[j]);
			}
			ArrayList<DataBloc> toEncrypt = DataBloc.toDataBlocs(result);
			C = blocEncrypter.encrypt(toEncrypt.get(0));
			cypherTextDataBloc.add(C);
		}

		return DataBloc.toBytes(cypherTextDataBloc);
	}

	@Override
	public String decrypt(byte[] cyphetText) {

		ArrayList<DataBloc> cypherTextDataBloc = DataBloc
				.toDataBlocs(cyphetText);

		DataBloc Ci_1 = null;

		ArrayList<DataBloc> plainTextData = new ArrayList<DataBloc>();

		int i = 0;
		for (DataBloc dataBloc : cypherTextDataBloc) {
			if (i != 0) {
				byte[] Ci_1Bytes = Ci_1.getBytes();

				DataBloc DecryptDataBlock = blocEncrypter.decrypt(dataBloc);

				byte[] CiBytes = DecryptDataBlock.getBytes();

				byte[] XorResult = new byte[CiBytes.length];

				for (int j = 0; j < CiBytes.length; j++) {
					XorResult[j] = (byte) (Ci_1Bytes[j] ^ CiBytes[j]);
				}
				ArrayList<DataBloc> plainText = DataBloc.toDataBlocs(XorResult);
				plainTextData.add(plainText.get(0));
			}
			Ci_1 = dataBloc;
			i++;
		}

		return DataBloc.toString(plainTextData);
	}

	public Key getKey(int i) {
		return ((TDEA) blocEncrypter).getKey(i);
	}

	public void setKey(int i, Key k) {
		((TDEA) blocEncrypter).setKey(i, k);
	}

	/**
	 * génère le vecteur initial
	 * 
	 * @return
	 */
	public DataBloc generateIV() {
		byte b[] = new byte[8];
		Random r = new Random();
		r.nextBytes(b);
		ArrayList<DataBloc> data = DataBloc.toDataBlocs(b);
		return data.get(0);
	}

	public static void main(String[] args) {
		TdeaCbc tdeaCbc = new TdeaCbc(KeyingOption.KeyingOption1);
		String originalText = "Il était une fois dans l'ouest.";
		byte[] cypherText = tdeaCbc.encrypt(originalText);
		String plainText = tdeaCbc.decrypt(cypherText);
		System.out.println(originalText);
		System.out.println(cypherText.toString());
		System.out.println(plainText);
	}
}
